class Requisicao < ActiveRecord::Base
  belongs_to :usuario
  has_many :sistemas, :through => :modulos
  has_and_belongs_to_many :modulos
  has_one :arquivo
  has_many :bd_items
  has_many :proiv_items
  has_many :historicos
  has_and_belongs_to_many :certificadores
  has_and_belongs_to_many :desenvolvedores
  
  # Validações
  validates_presence_of(:descricao, :message => "Campo obrigatório")
  
  acts_as_state_machine :initial => :criada, :column => 'estado'
  
  #Adicionar a descrição de cada estado no requisicoes_helper.rb
  ##################################################################################
  ###################### 001_fluxo_principal ESTADOS ###############################
  ##################################################################################
  state :criada #Criada
  state :certificacaoDispensada #Certificação dispensada
  state :aguardandoAutorizacaoGerencia #Aguardado autorização da gerência
  state :atualizacaoAutorizadaGerencia #Atualização autorizada pela gerência
  ##################################################################################
  ###################### 002_fluxo_desenvolvimento ESTADOS #########################
  ##################################################################################
  state :aguardandoDesenvolvimento # Aguardando Desenvolvimento
  state :escaladaParaDesenvolvedor # Escalada para Desenvolvimento
  state :desenvolvimentoSuspenso # Desenvolvimento Suspenso
  state :emDesenvolvimento # Em desenvolvimento
  state :desenvolvimentoConcluido # Desenvolvimento Concluído
  state :desenvolvimentoReprovadoPool # Desenvolvimento Reprovado (Pool)
  state :desenvolvimentoReprovadoAnal # Desenvolvimento Reprovado (Analista)
  state :desenvolvimentoAprovadoPool # Desenvolvimento Aprovado (Pool)
  state :desenvolvimentoAprovadoAnal # Desenvolvimento Aprovado (Analista)
  
  ##################################################################################
  ##################### 003_fluxo_certificacao ESTADOS #############################
  ##################################################################################
  #  state :dadosCertificacaoAlterada # Dados de Certificação Alterados
  #  state :scriptsBdExecutado # Scripts de Banco Executados
  #  state :propostoAdiamentoPrazo # Proposto Adiamento de Prazo
  #  state :erroScriptBdCert # Erro na Execução dos Scripts de Banco
  #  state :erroScriptAntCert # Erro na Execução do Script ANT
  #  state :scriptAntExecutadoCert # Script ANT Executado
  #  state :erroAtualizacaoBdCert # Erro na Atualização de Banco (Certificação)
  #  state :erroAtualizacaoServidorCert # Erro na Atualização de Servidor (Certificação)
  state :aguardandoCertificacao # Aguardando Certificação
  state :certificacaoCancelada # Certificação Cancelada
  state :certificacaoSuspensa # Certificação Suspensa
  state :escaladaCert # Escalada para Certificação
  state :emCert # Em Certificação
  state :aguardandoAtualizacaoBdCert # Aguardando Atualização de Banco (Certificação)
  state :atualizacaoBdCanceladaCert # Atualização de Banco Cancelada (Certificação)
  state :atualizacaoBdSuspensaCert # Atualização de Banco Suspensa (Certificação)
  state :atualizacaoBdIniciadaCert # Atualização de Banco Iniciada (Certificação)  
  state :atualizacaoBdConcluidaCert # Atualização de Banco Concluída (Certificação)
  state :aguardandoAtualizacaoServidorCert # Aguardando Atualização de Servidor (Certificação)
  state :atualizacaoServidorConcluidaCert # Atualização de Servidor Concluída (Certificação)
  state :atualizacaoServidorCanceladaCert # Atualização de Servidor Cancelada (Certificação)  
  state :atualizacaoServidorIniciadaCert # Atualização de Servidor Iniciada (Certificação)  
  state :atualizacaoServidorSuspensaCert # Atualização de Servidor Suspensa (Certificação)    
  state :requisicaoReprovadaCert # Requisição Reprovada (Certificação)
  state :requisicaoAprovadaCert # Requisição Reprovada (Certificação)
  
  ##################################################################################
  ############################ 004_fluxo_producao ##################################
  ##################################################################################
  #  state :erroAtualizacaoServidorProd # Erro na Atualização de Servidor (Produção)
  #  state :erroAtualizacaoBdProd # Erro na Atualização de Banco (Produção) 
  state :autorizadoEnvioProducao #Envio para produção autorizado
  state :aguardandoAutorizacaoGerenteProd # Aguardando Autorizacao do Gerente (Produção)
  state :aguardandoAtualizacaoProd # Aguardando Atualização de Produção
  state :aguardandoAtualizacaoBdProd # Aguardando Atualização de Banco (Produção)
  state :atualizacaoBdIniciadaProd # Atualização de Banco Iniciada (Produção)
  state :atualizacaoBdCanceladaProd # Atualização de Banco Cancelada (Produção)
  state :atualizacaoBdConcluidaProd # Atualização de Banco Concluída (Produção)
  state :atualizacaoBdSuspensaProd # Atualização de Banco Suspensa (Produção)  
  state :aguardandoAtualizacaoServidorProd # Aguardando Atualização de Servidor (Produção)
  state :atualizacaoServidorIniciadaProd  # Atualização de Servidor Iniciada (Produção)
  state :atualizacaoServidorCanceladaProd # Atualização de Servidor Cancelada (Produção)
  state :atualizacaoServidorConcluidaProd # Atualização de Servidor Concluída (Produção)
  state :atualizacaoServidorSuspensaProd # Atualização de Servidor Suspensa (Produção)  
  state :requisicaoEmProd # Requisição em Produção
  state :erroNaProducao # Erro na Produção
  state :atualizacaoProducaoSolicitada # Atualização de Produção Solicitada
  
  ##################################################################################
  ######################### 001_fluxo_principal EVENTOS  ###########################
  ##################################################################################
  event(:enviarParaAtualizacaoProducao) do
    transitions({:from => :criada, :to => :certificacaoDispensada})
    transitions({:from => :desenvolvimentoAprovadoAnal, :to => :certificacaoDispensada})    
    #transitions({:from => :requisicaoAprovadaCert, :to => :atualizacaoProducaoSolicitada})    
  end
  
  
  event(:enviarParaDesenvolvimento) do
    transitions({:from => :criada, :to => :aguardandoDesenvolvimento})
  end
  
  event(:dispensarCertificacao) do 
    #transição automatica de :enviarParaAtualizacaoProducao
    transitions({:from => :certificacaoDispensada, :to => :aguardandoAutorizacaoGerencia}) 
  end
  
  event(:atualizarImediatamente) do
    #transição automatica de acordo com a opção do certificador
    #Atualizar imediatamente ou enviar para produção
    transitions({:from => :requisicaoAprovadaCert, :to => :aguardandoAutorizacaoGerencia})
  end
  
  event(:autorizarAtualizacao) do 
    transitions({:from => :aguardandoAutorizacaoGerencia, :to => :atualizacaoAutorizadaGerencia}) 
  end  
  
  event(:atualizacaoAutorizada) do
    #transição automatica   de :autorizarAtualizacao
    transitions({:from => :atualizacaoAutorizadaGerencia , :to => :aguardandoAtualizacaoProd})
  end
  ################################################################################## 
  ##################### 002_fluxo_desenvolvimento EVENTOS ##########################
  ##################################################################################
  event(:escalarDesenvolvedor) do 
    transitions({:from => :aguardandoDesenvolvimento, :to => :escaladaParaDesenvolvedor}) 
    transitions({:from => :desenvolvimentoSuspenso, :to => :escaladaParaDesenvolvedor}) 
    transitions({:from => :desenvolvimentoReprovadoPool, :to => :escaladaParaDesenvolvedor})     
    transitions({:from => :desenvolvimentoReprovadoAnal, :to => :escaladaParaDesenvolvedor})     
  end  
  
  event(:iniciarDesenvolvimento) do 
    transitions({:from => :escaladaParaDesenvolvedor, :to => :emDesenvolvimento}) 
    transitions({:from => :desenvolvimentoSuspenso, :to => :emDesenvolvimento}) 
  end
  
  event(:suspenderDesenvolvimento) do 
    transitions({:from => :emDesenvolvimento, :to => :desenvolvimentoSuspenso}) 
  end   
  
  
  event(:concluirDesenvolvimento) do 
    transitions({:from => :emDesenvolvimento, :to => :desenvolvimentoConcluido}) 
  end
  
  event(:reprovarDesenvolvimento) do 
    transitions({:from => :desenvolvimentoConcluido, :to => :desenvolvimentoReprovadoPool}) 
  end

  event(:reprovarDesenvolvimentoAnalista) do 
    transitions({:from => :desenvolvimentoAprovadoPool, :to => :desenvolvimentoReprovadoAnal})     
  end
  
  event(:aprovarDesenvolvimento) do 
    transitions({:from => :desenvolvimentoConcluido, :to => :desenvolvimentoAprovadoPool}) 
    transitions({:from => :desenvolvimentoAprovadoPool, :to => :desenvolvimentoAprovadoAnal})     
  end  
  event(:aprovarDesenvolvimentoAnalista) do
    transitions({:from => :desenvolvimentoAprovadoPool, :to => :desenvolvimentoAprovadoAnal})         
  end
  
  ##################################################################################
  ########################## 003_fluxo_certificacao EVENTOS ########################
  ##################################################################################
  event(:enviarParaCertificacao) do 
    transitions({:from => :criada, :to => :aguardandoCertificacao})
    transitions({:from => :desenvolvimentoAprovadoAnal, :to => :aguardandoCertificacao})    
    transitions({:from => :certificacaoCancelada, :to => :aguardandoCertificacao})        
    transitions({:from => :requisicaoReprovadaCert, :to => :aguardandoCertificacao})            
  end
  
  event(:cancelarCert) do
    transitions({:from => :aguardandoCertificacao, :to => :certificacaoCancelada})
  end
  
  event(:escalarCertificador) do 
    transitions({:from => :aguardandoCertificacao, :to => :escaladaCert}) 
    transitions({:from => :certificacaoSuspensa, :to => :escaladaCert})     
    transitions({:from => :atualizacaoBdConcluidaCert, :to => :escaladaCert})      
    transitions({:from => :atualizacaoServidorConcluidaCert, :to => :escaladaCert})          
  end
  
  event(:iniciarCertificacao) do
    transitions({:from => :escaladaCert, :to => :emCert})
    transitions({:from => :certificacaoSuspensa, :to => :emCert})
    transitions({:from => :atualizacaoBdConcluidaCert, :to => :emCert})
    transitions({:from => :atualizacaoServidorConcluidaCert, :to => :emCert})    
  end
  
  
  event(:solicitarAtualizacaoBdCert) do
    transitions({:from => :aguardandoCertificacao, :to => :aguardandoAtualizacaoBdCert})
    transitions({:from => :atualizacaoBdCanceladaCert, :to => :aguardandoAtualizacaoBdCert})
    transitions({:from => :emCert, :to => :aguardandoAtualizacaoBdCert})
  end
  
  event(:cancelarAtualizacaoBdCert) do
    transitions({:from => :aguardandoAtualizacaoBdCert, :to => :atualizacaoBdCanceladaCert})
  end
  
  event(:iniciarAtualizacaoBdCert) do
    transitions({:from => :aguardandoAtualizacaoBdCert, :to => :atualizacaoBdIniciadaCert})
    transitions({:from => :atualizacaoBdSuspensaCert, :to => :atualizacaoBdIniciadaCert})
  end
  
  event(:suspenderAtualizacaoBdCert) do
    transitions({:from => :atualizacaoBdIniciadaCert, :to => :atualizacaoBdSuspensaCert})
  end
  
  event(:concluirAtualizacaoBdCert) do
    transitions({:from => :atualizacaoBdIniciadaCert, :to => :atualizacaoBdConcluidaCert})
  end
  # Servidor
  event(:solicitarAtualizacaoServidorCert) do
    transitions({:from => :aguardandoCertificacao, :to => :aguardandoAtualizacaoServidorCert})
    transitions({:from => :atualizacaoServidorCanceladaCert, :to => :aguardandoAtualizacaoServidorCert})
    transitions({:from => :emCert, :to => :aguardandoAtualizacaoServidorCert})
  end
  
  event(:cancelarAtualizacaoServidorCert) do
    transitions({:from => :aguardandoAtualizacaoServidorCert, :to => :atualizacaoServidorCanceladaCert})
  end
  
  event(:iniciarAtualizacaoServidorCert) do
    transitions({:from => :aguardandoAtualizacaoServidorCert, :to => :atualizacaoServidorIniciadaCert})
    transitions({:from => :atualizacaoServidorSuspensaCert, :to => :atualizacaoServidorIniciadaCert})
  end
  
  event(:suspenderAtualizacaoServidorCert) do
    transitions({:from => :atualizacaoServidorIniciadaCert, :to => :atualizacaoServidorSuspensaCert})
  end
  
  event(:concluirAtualizacaoServidorCert) do
    transitions({:from => :atualizacaoServidorIniciadaCert, :to => :atualizacaoServidorConcluidaCert})
  end
  
  event(:reprovarRequisicao) do
    transitions({:from => :emCert, :to => :requisicaoReprovadaCert})
  end
  
  event(:aprovarRequisicao) do
    transitions({:from => :emCert, :to => :requisicaoAprovadaCert})
  end
  
  event(:suspenderCertificacao)do
    transitions({:from => :emCert, :to => :certificacaoSuspensa})
  end
  
  event(:enviarParaProd) do
    #transição automatica de acordo com a opção do certificador; 
    #Atualizar imediatamente ou enviar para produção
    transitions({:from => :requisicaoAprovadaCert, :to => :aguardandoAtualizacaoProd})
  end
  ################################################################################## 
  ######################## 004_fluxo_produção EVENTOS ############################## 
  ##################################################################################
  
  # Bd
  event(:naoAtualizaBdProd) do
    #transição atomatica de acordo com a escolha do certificador q aprovou a requisição    
    transitions({:from => :aguardandoAtualizacaoProd, :to => :aguardandoAtualizacaoServidorProd})   
    transitions({:from => :autorizadoEnvioProducao, :to => :aguardandoAtualizacaoServidorProd})       
  end
  
  event(:atualizaBdProd) do
    #transição atomatica de acordo com a escolha do certificador q aprovou a requisição    
    transitions({:from => :aguardandoAtualizacaoProd, :to => :aguardandoAtualizacaoBdProd})      
    transitions({:from => :autorizadoEnvioProducao, :to => :aguardandoAtualizacaoBdProd})         
  end
  
  event(:iniciarAtualizacaoBdProd) do
    transitions({:from => :aguardandoAtualizacaoBdProd, :to => :atualizacaoBdIniciadaProd})      
    transitions({:from => :atualizacaoBdSuspensaProd, :to => :atualizacaoBdIniciadaProd})      
  end
  
  event(:suspenderAtualizacaoBdProd) do 
    transitions({:from => :atualizacaoBdIniciadaProd, :to => :atualizacaoBdSuspensaProd})
  end
  
  event(:cancelarAtualizacaoBdProd) do 
    transitions({:from => :atualizacaoBdIniciadaProd, :to => :atualizacaoBdCanceladaProd})
  end
  
  event(:solicitarAtualizacaoBdProd) do
    #ação do analista. Ao estar no estado atualizacaoBdCanceladaProd 
    #aparece como suspensa na home do analista
    transitions({:from => :atualizacaoBdCanceladaProd, :to => :aguardandoAtualizacaoBdProd})
  end
  
  event(:concluirAtulizacaoBdProd) do
    transitions({:from => :atualizacaoBdIniciadaProd, :to => :atualizacaoBdConcluidaProd})    
  end
  
  # Servidor 
  
  event(:naoAtualizaServidorProd) do
    #transição atomatica de acordo com a escolha da produção    
    transitions({:from => :atualizacaoBdConcluidaProd, :to => :requisicaoEmProd})      
  end
  
  event(:atualizaServidorProd) do
    #transição atomatica de acordo com a escolha da produção
    transitions({:from => :atualizacaoBdConcluidaProd, :to => :aguardandoAtualizacaoServidorProd})      
  end
  
  event(:iniciarAtualizacaoServidorProd) do
    transitions({:from => :aguardandoAtualizacaoServidorProd, :to => :atualizacaoServidorIniciadaProd})      
    transitions({:from => :atualizacaoServidorSuspensaProd, :to => :atualizacaoServidorIniciadaProd})      
  end
  
  event(:suspenderAtualizacaoServidorProd) do 
    transitions({:from => :atualizacaoServidorIniciadaProd, :to => :atualizacaoServidorSuspensaProd})
  end
  
  event(:cancelarAtualizacaoServidorProd) do 
    transitions({:from => :atualizacaoServidorIniciadaProd, :to => :atualizacaoServidorCanceladaProd})
  end
  
  event(:solicitarAtualizacaoServidorProd) do
    #ação do analista. Ao estar no estado atualizacaoServidorCanceladaProd 
    #aparece como suspensa na home do analista
    transitions({:from => :atualizacaoServidorCanceladaProd, :to => :aguardandoAtualizacaoServidorProd})
  end
  
  event(:concluirAtulizacaoServidorProd) do
    transitions({:from => :atualizacaoServidorIniciadaProd, :to => :atualizacaoServidorConcluidaProd})    
  end
  
  event(:enviarParaProducao) do
    #transição automatica de fim do processo
    transitions({:from => :atualizacaoServidorConcluidaProd, :to => :requisicaoEmProd})    
  end
  
  event(:reportarErroProducao) do
    transitions({:from => :requisicaoEmProd , :to => :erroNaProducao})
  end
  
  #producao
  event(:necessitaAutoriazaoGerenteProd) do
    transitions({:from => :atualizacaoAutorizadaGerencia, :to => :aguardandoAutorizacaoGerenteProd})
    transitions({:from => :requisicaoAprovadaCert, :to => :aguardandoAutorizacaoGerenteProd})    
  end
  
  event(:autorizaEnvioProd) do
    transitions({:from => :aguardandoAutorizacaoGerenteProd, :to => :autorizadoEnvioProducao})
  end

end